AI 도구 개발

AI챗봇_02_Hello Spring Boot와 LLM

작성자 : Heehyeon Yoo|2026-01-10
# Spring Boot# Spring AI# Docker# Kotlin# Troubleshooting

Hello World

프로젝트 세팅의 첫 단계는 언제나 Hello World를 띄우는 것이다.
하지만 내 개발 환경은 오래전 설치한 JDK 14와 최신 JDK 24가 뒤섞여 있었고, 1GB 램의 오라클 클라우드(Oracle Cloud) 인스턴스는 최신 무거운 프레임워크를 감당하기 버거워했다.

처음엔 호기롭게 최신 스택(Spring Boot 3.4.1 + Kotlin 2.x)으로 시작했다.
도커(Docker)의 Multi-staging Build를 이용해 빌드 환경과 실행 환경을 분리하고, 경량화된 Alpine Linux 위에서 돌려보려 했지만... 실패했다.
최신 라이브러리 간의 미묘한 버전 충돌과 Alpine 리눅스의 시스템 라이브러리 부재가 겹치면서 예측 불가능한 에러들이 터져 나왔다.

Back to the Golden Stack

지금 중요한 건 "최신 기술 찍먹"이 아니라 "안정적으로 돌아가는 챗봇 서버"였다.
결국 버전을 낮춰 가장 안정적이라고 평가받는, 일명 Golden Stack으로 회귀를 결정했다.

  • Spring Boot: 3.4.1 → 3.2.0
  • Kotlin: 2.x → 1.9.20
  • Base Image: eclipse-temurin:17-jre-alpine

이 조합으로 Dockerfile을 수정하고 다시 빌드를 돌리자, 그제야 약 180MB 남짓한 가벼운 챗봇 서버가 정상적으로 숨을 쉬기 시작했다.

> curl localhost:8080
Hello World! This is Spring Boot from 1GB Server.

서버에 두뇌 장착하기

서버가 떴으니 이제 두뇌를 달아줄 차례다.
LangChain4j도 훌륭하지만, Spring 생태계와의 통합성을 고려해 Spring AI를 선택했다.

문제는 앞서 선택한 Golden Stack(Spring Boot 3.2.0)과 호환되는 버전을 찾는 것이었다. Spring AI는 아직 초기 단계라 버전 민감도가 매우 높다.
확인 결과 Spring AI 0.8.1이 Spring Boot 3.2.x와 호환되는 마지노선이었다.

아직 Maven Central에 정식 배포되지 않은 라이브러리도 있어 spring-milestones 리포지토리를 추가해야 했다.

// build.gradle.kts
repositories {
    mavenCentral()
    maven("https://repo.spring.io/milestone")
    maven("https://repo.spring.io/snapshot")
}

dependencyManagement {
    imports {
        mavenBom("org.springframework.ai:spring-ai-bom:0.8.1")
    }
}

보안과 첫 대화

API Key 관리는 언제나 중요하다.
application.yml에서는 환경 변수만 참조하게 두고,

spring:
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}

실제 키는 Docker 컨테이너를 실행할 때 -e 옵션으로 주입하거나, 서버의 .env 파일에서 읽어오도록 구성했다. 이렇게 하면 소스 코드에는 아무런 흔적이 남지 않는다.

첫 대화

간단한 ChatController를 만들어서 AI에게 말을 걸어보았다.
복잡한 RAG 로직 없이, ChatClient가 OpenAI에게 내 말을 그대로 전달하고 답변을 받아오는 구조다.

@GetMapping("/chat")
fun chat(@RequestParam message: String): String {
    return chatClient.call(message)
}

터미널에서 요청을 보내고 잠시 후, 첫 답변이 돌아왔다.

> curl "localhost:8080/api/chat?message=Hello"
Hello! How can I assist you today?

이제 서버가 "생각"을 할 수 있게 되었다.
다음에는 RAG(검색 증강 생성)를 구현해보자.